package com.castile.sdk.nifi.client.config;

import org.apache.nifi.security.ssl.StandardKeyStoreBuilder;
import org.apache.nifi.security.ssl.StandardSslContextBuilder;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyStore;

/**
 *
 * NiFI 集群的配置信息, 从配置中心获取
 *
 * @author castile
 * @date 2025-05-12 下午11:09
 */
public class NiFiConfig {
    private String baseUrl;
    private Integer connectTimeout;
    private String protocol = "TLS";
    private HostnameVerifier hostnameVerifier;
    private Integer readTimeout;

    private SSLContext sslContext;
    private String keystoreFilename;
    private String keystorePass;
    private String keyPass;
    private String keystoreType = "jks";
    private String truststoreFilename;
    private String truststorePass;
    private String truststoreType = "jks";
    /**
     * 配置名称
     */
    private String name = "default_nifi";

    public NiFiConfig() {
    }

    public NiFiConfig(String baseUrl, String name) {
        this.baseUrl = baseUrl;
        this.name = name;
    }

    public NiFiConfig(String protocol, HostnameVerifier hostnameVerifier, Integer readTimeout, Integer connectTimeout) {
        this.protocol = protocol;
        this.hostnameVerifier = hostnameVerifier;
        this.readTimeout = readTimeout;
        this.connectTimeout = connectTimeout;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBaseUrl() {
        return baseUrl;
    }

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public Integer getConnectTimeout() {
        return connectTimeout;
    }

    public void setConnectTimeout(Integer connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    public String getProtocol() {
        return protocol;
    }

    public HostnameVerifier getHostnameVerifier() {
        return hostnameVerifier;
    }

    public Integer getReadTimeout() {
        return readTimeout;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
        this.hostnameVerifier = hostnameVerifier;
    }

    public void setReadTimeout(Integer readTimeout) {
        this.readTimeout = readTimeout;
    }

    public SSLContext getSslContext() {
        if (sslContext != null) {
            return sslContext;
        }

        final KeyStore keyStore;
        if (keystoreFilename != null && keystorePass != null && keystoreType != null) {
            try (final InputStream keyStoreStream = Files.newInputStream(Paths.get(keystoreFilename))) {
                keyStore = new StandardKeyStoreBuilder()
                        .inputStream(keyStoreStream)
                        .password(keystorePass.toCharArray())
                        .type(keystoreType)
                        .build();
            } catch (final IOException e) {
                throw new IllegalStateException(String.format("Read Key Store [%s] failed", keystoreFilename), e);
            }
        } else {
            keyStore = null;
        }

        final KeyStore trustStore;
        if (truststoreFilename != null && truststorePass != null && truststoreType != null) {
            try (final InputStream keyStoreStream = Files.newInputStream(Paths.get(truststoreFilename))) {
                trustStore = new StandardKeyStoreBuilder()
                        .inputStream(keyStoreStream)
                        .password(truststorePass.toCharArray())
                        .type(truststoreType)
                        .build();
            } catch (final IOException e) {
                throw new IllegalStateException(String.format("Read Trust Store [%s] failed", truststoreFilename), e);
            }
        } else {
            trustStore = null;
        }

        if (keyStore != null || trustStore != null) {
            final StandardSslContextBuilder builder = new StandardSslContextBuilder();
            builder.protocol(protocol);

            if (keyStore != null) {
                final char[] keyPassword = keyPass == null ? keystorePass.toCharArray() : keyPass.toCharArray();
                builder.keyPassword(keyPassword);
                builder.keyStore(keyStore);
            }
            if (trustStore != null) {
                builder.trustStore(trustStore);
            }
            return builder.build();
        } else {
            return null;
        }
    }

    public void setSslContext(SSLContext sslContext) {
        this.sslContext = sslContext;
    }

    public String getKeystoreFilename() {
        return keystoreFilename;
    }

    public void setKeystoreFilename(String keystoreFilename) {
        this.keystoreFilename = keystoreFilename;
    }

    public String getKeystorePass() {
        return keystorePass;
    }

    public void setKeystorePass(String keystorePass) {
        this.keystorePass = keystorePass;
    }

    public String getKeyPass() {
        return keyPass;
    }

    public void setKeyPass(String keyPass) {
        this.keyPass = keyPass;
    }

    public String getKeystoreType() {
        return keystoreType;
    }

    public void setKeystoreType(String keystoreType) {
        this.keystoreType = keystoreType;
    }

    public String getTruststoreFilename() {
        return truststoreFilename;
    }

    public void setTruststoreFilename(String truststoreFilename) {
        this.truststoreFilename = truststoreFilename;
    }

    public String getTruststorePass() {
        return truststorePass;
    }

    public void setTruststorePass(String truststorePass) {
        this.truststorePass = truststorePass;
    }

    public String getTruststoreType() {
        return truststoreType;
    }

    public void setTruststoreType(String truststoreType) {
        this.truststoreType = truststoreType;
    }
}
